<!--
  create by 李益钢 at 2020-03-10 简单表格通用组件
-->
<template>
  <!-- 多选返回事件 changeRow -->
  <div>
    <!--表格-->
    <el-table
      v-loading="isShowLoading?isLoading: false"
      ref="commonTableRef"
      :data="dataList"
      style="width: 100%;position: relative;"
      border
      :row-key="rowKeyFunc"
      class="commonTable"
      :header-cell-class-name="cellClass"
      highlight-current-row
      :max-height="tHeight"
      @cell-mouse-enter="cellMouseEnter"
      @sort-change="sortChange"
      @selection-change="handleSelectionChange"
      @current-change="rowClickMethods"
      @expand-change="expandChangeMethods"
    >
      <el-table-column
        v-if="$props.isShowExpand"
        type="expand"
      >
        <template slot-scope="scope">
          <slot
            name="expandSlot"
            :row="scope.row"
            :arrIndex="scope.$index"
          />
        </template>
      </el-table-column>
      <el-table-column
        v-if="$props.isSelection"
        :selectable="checkIsCanSelect"
        :reserve-selection="$props.isReserveSelect"
        type="selection"
        width="55"
      />
      <el-table-column
        v-if="$props.isShowIndex"
        type="index"
        width="50"
        label="序号"
      />
      <!--:show-overflow-tooltip="true"-->
      <el-table-column
        v-for="(item , index) in getCol"
        :key="item.prop + '-' + index + '-' + 'only'"
        :align="item.align?item.align: 'left'"
        :prop="item.prop"
        :label="item.label"
        :data-colIndex="index"
        :min-width="item.width"
        :sortable="item.sortable || false"
        :fixed="item.fixed?item.fixed: false"
      >
        <template slot-scope="scope">
          <div v-if="item.filter && item.filter === 'date'">
            {{ scope.row[item.prop] | transformDate }}
          </div>
          <!--          <div v-else-if="item.filter && item.filter === 'times'">-->
          <!--            {{scope.row[item.prop] | transformTimes}}-->
          <!--          </div>-->
          <div v-else-if="item.filter && item.filter === 'percent'">
            {{ scope.row[item.prop].toFixed(2) }}%
          </div>
          <!--有值存在-->
          <div v-else-if="item.filter && item.filter === 'keyValue' && scope.row[item.prop] !== undefined && scope.row[item.prop] !== null">
            {{ item.options[scope.row[item.prop]] }}
          </div>
          <div v-else-if="item.isEdit && item.inputType === 'string'">
            <input
              v-model="scope.row[item.prop]"
              type="text"
              style="padding: 3px;border-radius: 4px;border: 1px solid lightgrey;"
              @blur="blurInputValue(item.prop , scope.$index , scope.row[item.prop] , item.validateType , scope.row)"
            >
          </div>
          <!--开关控件-->
          <div v-else-if="item.isEdit && item.inputType === 'switch'">
            <el-switch
              :value="scope.row[item.prop]"
              :active-value="item.switchOpt[0]"
              :inactive-value="item.switchOpt[1]"
              active-color="#13ce66"
              inactive-color="#999999"
              @change="updateStatus(item.prop , scope.row , scope.$index , item.switchOpt)"
            />
          </div>
          <!--单选下拉控件-->
          <div v-else-if="item.isEdit && item.inputType === 'select'">
            <el-select
              v-model="scope.row[item.prop]"
              placeholder="请选择"
              @change="refreshView"
            >
              <el-option
                v-for="(im , idx) in item.dataSource"
                :key="idx"
                :label="im.label"
                :value="im.value"
              />
            </el-select>
          </div>
          <!--自定义 slotName 插槽名称-->
          <div v-else-if="item.prop === 'slot'">
            <slot
              :name="item.slotName"
              :row="scope.row"
              :arrIndex="scope.$index"
            />
          </div>
          <div v-else-if="item.popover">
            <el-popover
              placement="top-start"
              trigger="hover"
              :content="scope.row[item.prop]"
            >
              <el-button
                slot="reference"
                :style="{width: item.width + 'px', overflow: 'hidden', textOverflow: 'ellipsis'}"
                type="text"
              >
                {{ scope.row[item.prop] }}
              </el-button>
            </el-popover>
          </div>
          <!--为了有些格式渲染-->
          <div
            v-else-if="item.renderMethods === 'html'"
            v-html="scope.row[item.prop]"
          />
          <template
            v-else
          >
            <span>{{ scope.row[item.prop] }}</span>
          </template>
        </template>
      </el-table-column>

      <el-table-column
        v-if="$props.isHasOpera"
        fixed="right"
        :min-width="operatingWidth"
        label="操作"
      >
        <template slot-scope="scope">
          <slot
            name="operate"
            :row="scope.row"
            :arrIndex="scope.$index"
          />
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      v-if="isShowPageControl"
      class="page-nation"
      :current-page="searchObj.page"
      :page-sizes="[10, 20, 30, 40]"
      :page-size="searchObj.pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script>
// import {FormatDate} from '@/utils/filters'
import {formatMediaTypeStr} from '@/utils/config'
import {sortCNOrder} from "@/utils/utils";
export default {
  name: 'RulesCommonTable',
  filters: {
    transformDate: function(value) {
      if (value) {
        return this.formatDate(new Date(value))
      }
      return ''
    },
    // transformTimes(value) {
    //   if (value) {
    //     return FormatDate(new Date(value)).split(' ')[1]
    //   }
    //   return ''
    // }
  },
  props: {
    onlyUpdateFields: {
      type: String,
      default: ''
    },
    isShowPageControl: {
      type: Boolean,
      default: true
    },
    isShowExpand: {
      type: Boolean,
      default: false
    },
    isShowLoading: {
      type: Boolean,
      default: true
    },
    // 控制操作是否fixed
    operateIsFixed: {
      type: String,
      default: ''
    },
    // 控制操作的长度默认是空
    operatingWidth: {
      type: String || Number,
      default: "190"
    },
    // 是否显示序列号
    isShowIndex: {
      type: Boolean,
      default: true
    },
    // 是否展示操作
    isHasOpera: {
      type: Boolean,
      default: true
    },
    // 是否展示跨页全选
    isReserveSelect: {
      type: Boolean,
      default: false
    },
    // 当前第几页
    currentPage: {
      type: Number,
      default: 1
    },
    // 默认发射选中的方法名
    emitSelectionName: {
      type: String,
      default: 'changeRow'
    },
    isSelection: {
      type: Boolean,
      default: false
    },
    tColumnData: {
      type: Array,
      default: () => []
    },
    tData: {
      type: Array,
      default: () => []
    },
    isSelect: {
      type: Boolean,
      default: false
    },
    tHeight: {
      type: Number,
      default: 1030
    },
    rowKey: {
      type: String,
      default: 'id'
    },
    remoteApi: {
      type: Function | String,
      default: ''
    },
    queryParams: {
      type: Object,
      default: () => {}
    },
    isAllSelection: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      itemWithChildren: [], //遍历子级临时数组
      isLoading: false,
      searchObj: {
        page: 1,
        pageSize: 20,
        // size: 10
      },
      total: 0,
      selectedCache: [],
      rowKeyFunc: (row) => {
        // console.log('row ---', row, row[this.rowKey])
        return `${row[this.rowKey]}`
      },
      dataList: [],
      historyDataList: []
    }
  },
  computed: {
    // 过滤isShow 不展示的值
    getCol() {
      const tmp = []
      this.$props.tColumnData.forEach((v) => {
        if (v.isShow) {
          tmp.push(v)
        }
      })
      return tmp
    }
  },
  watch: {
    // 判断选中中是否还有数据，没有就清空选中状态
    selectedCache() {
      // if (this.selectedCache.length === 0) {
      //   this.$refs.commonTableRef.clearSelection()
      // }
    },
    // tData(val) {
    //   if(this.remoteApi == '') {
    //     this.dataList = val.slice()
    //   }
    // }
  },
  mounted() {
    // 如果有remoteapi 就从接口获取数据
    if(this.remoteApi !== '') {
      const params = {
        ...this.searchObj,
        ...this.queryParams
      }
      // this.getRemoteList(params)
    }
    this.$nextTick(() => {
      let calWidth = 0
      this.$props.tColumnData.forEach((v) => {
        calWidth = parseInt(calWidth, 10) + parseInt(v.width, 10)
      })
      if(this.$refs.commonTableRef) {
        const documentWidth = parseInt(this.$refs.commonTableRef.bodyWidth.split('p')[0], 10)
        if (calWidth < documentWidth && document.body.clientWidth > 1366) {
          this.$refs.commonTableRef.$el.style.width = '100%'
        }
      }

      // setTimeout(() => {
      //   this.tableWidthAdaptation()
      // }, 20)
    })
  },
  methods: {
    getTableData() {
      return this.dataList
    },
    setTableDataByIndex(data, index) {
      this.$set(this.dataList, index, data)
      this.dataList.splice(0, 0)
    },
    cellClass(row){
      // console.log('isAllSelection ---', this.isAllSelection, row)
      if(!this.isAllSelection){
        if (row.columnIndex === 0) {
          return 'DisableSelection'
        }
      }
    },
    clearOtherRowDisabled() {
      this.dataList.forEach((item) => {
        item.isCanSelected = 1
      })
    },
    checkIsCanSelect(row) {
      // console.log('isAllSelection ---', this.isAllSelection , row)
      return row.isCanSelected
    },
    sortDevName(row1, row2, props) {
      // console.log('props.customSort ---', props.customSort && props.customSort(row1, row2))
      return props.customSort && props.customSort(row1, row2)
    },
    getChartType(char) {
      // 数字可按照排序的要求进行自定义，我这边产品的要求是
      // 数字（0->9）->大写字母（A->Z）->小写字母（a->z）->中文拼音（a->z）
      if (/^[\u4e00-\u9fa5]$/.test(char)) {
        return ['zh', 300]
      }
      if (/^[a-zA-Z]$/.test(char)) {
        return ['en', 200]
      }
      if (/^[0-9]$/.test(char)) {
        return ['number', 100]
      }
      return ['others', 999]
    },
    cellMouseEnter(row, column) {
      this.$emit('on-cell-enter', {
        row,
        column
      })
    },
    resetPageNo() {
      this.searchObj.page = 1
    },
    handleCurrentChange(page) {
      this.searchObj.page = page
      this.queryData({})
    },
    handleSizeChange(size) {
      this.searchObj.size = size
      this.searchObj.pageSize = size
      this.queryData({})
    },
    queryData(obj, callback = () => {}) {
      const params = {
        ...this.queryParams,
        ...obj,
        ...this.searchObj,
      }
      if(this.$route.path === '/terminal/fileList') {
        delete params.size
      }
      if(obj.pageSize) {
        params.pageSize = obj.pageSize
      }
      this.getRemoteList(params, callback)
    },
    getRemoteList(params, callback = () => {}) {
      this.isLoading = true
      if(this.onlyUpdateFields === '') {
        this.dataList = []
        this.historyDataList = []
      }
      this.remoteApi(params).then((res) => {
        let dataTmp = res.data.records || res.data
        dataTmp.forEach((item) => {
          if(!item.group_name) {
            item.group_name = ''
          }
          if(item.name) {
            item.name = item.name.replaceAll('\u0000', '')
          }
          // if(item.media_type) {
          //   if(item.media_type != 5 && item.media_type != 8) {
          //     item.media_type = `${formatMediaTypeStr(item.media_type)} ${item.media_type != 1 && item.media_suffix != undefined?item.media_suffix: ''}`
          //   } else if(item.media_type == 5) {
          //     item.media_type = `${formatMediaTypeStr(item.media_type)}`
          //   } else if(item.media_type == 8) {
          //     item.media_type = '节目'
          //   }
          //   if(item.file_type == 1) {
          //     item.media_type = item.media_type + ' 文件夹'
          //   }
          // }
          if(item.media_name) {
            item.noSuffixMediaName = item.media_name.split('.')[0]
          }
        })

        if(this.onlyUpdateFields !== '') {
          if(this.dataList.length === 0) {
            this.dataList = dataTmp.slice()
            this.historyDataList = dataTmp.slice()
          } else {
            this.dataList.forEach((item, key) => {
              if(dataTmp[key]) {
                item[this.onlyUpdateFields] = dataTmp[key][this.onlyUpdateFields]
              }
            })
            this.historyDataList.forEach((item, key) => {
              if(dataTmp[key]) {
                item[this.onlyUpdateFields] = dataTmp[key][this.onlyUpdateFields]
              }
            })
          }
        } else {
          this.dataList = dataTmp.slice()
          this.historyDataList = dataTmp.slice()
        }
        this.dataList.forEach((item, key) => {
          this.$set(this.dataList[key], 'isCanSelected', 1)
        })
        this.dataList.splice(0, 0)
        console.log('this.dataList ---', this.dataList)
        this.total = res.data.total
        this.isLoading = false
        callback(res.data.records || [])
      })
    },
    formatDate(date, format) {
      if (!date) {
        return ''
      }

      let d = new Date(date)

      // 年
      if (/YYYY/.test(format)) {
        format = format.replace(/YYYY/, d.getFullYear())
      }
      // 月份
      let month = d.getMonth() + 1
      if (/MM/.test(format)) {
        let monthStr = month < 10 ? '0' + month : month
        format = format.replace(/MM/, monthStr)
      } else if (/M/.test(format)) {
        format = format.replace(/M/, month)
      }
      // 日期
      let dates = d.getDate()
      if (/DD/.test(format)) {
        let dateStr = dates < 10 ? '0' + dates : dates
        format = format.replace(/DD/, dateStr)
      } else if (/D/.test(format)) {
        format = format.replace(/D/, dates)
      }
      // 小时
      let hours = d.getHours()
      console.log('hours --', hours)
      if (/HH/.test(format)) {
        let hoursStr = hours < 10 ? '0' + hours : hours
        format = format.replace(/HH/, hoursStr)
      } else if (/H/.test(format)) {
        format = format.replace(/H/, hours)
      } else if (/hh/.test(format)) {
        let hoursMin = hours > 12 ? hours - 12 : hours
        let hoursStr = hoursMin < 10 ? '0' + hoursMin : hoursMin
        format = format.replace(/hh/, hoursStr)
      } else if (/h/.test(format)) {
        let hoursMin = hours > 12 ? hours - 12 : hours
        format = format.replace(/h/, hoursMin)
      }
      // 分
      let minutes = d.getMinutes()
      if (/mm/.test(format)) {
        let minutesStr = minutes < 10 ? '0' + minutes : minutes
        format = format.replace(/mm/, minutesStr)
      } else if (/m/.test(format)) {
        format = format.replace(/m/, minutes)
      }
      // 秒
      let seconds = d.getSeconds()
      if (/ss/.test(format)) {
        let secondsStr = seconds < 10 ? '0' + seconds : seconds
        format = format.replace(/ss/, secondsStr)
      } else if (/s/.test(format)) {
        format = format.replace(/s/, seconds)
      }
      return format
    },
    clearSelectionMethods() {
      this.$refs.commonTableRef.clearSelection()
    },
    sortChange(col) {
      // this.sortMethods(col)
      // return props.customSort && props.customSort(row1, row2)
      const { column, prop, order } = col
      const params = [...this.dataList]
      if(order) {
        this.getCol.forEach((item) => {
          if(item.sortable === 'custom') {
            this.dataList = item.customSort && item.customSort(params, order)
          }
        })
        this.$emit('sortMethods',col);
      } else {
        console.log('取消排序 ')
        this.dataList = [...this.historyDataList]
      }
    },
    columnWidth(value, min = 52, max = 200) {
      console.log('value ---', value)
      value = Number(value) + 12
      if (value < min) {
        return min + 'px'
      } else if (value > max) {
        return max + 'px'
      } else {
        return value + 'px'
      }
    },
    tableWidthAdaptation() {
      const rows = this.$refs.commonTableRef.$el.childNodes[2].childNodes[0].childNodes[1].rows
      const arr = []
      for (let i = 0; i < rows.length; i++) {
        for (let j = 0; j < rows[i].cells.length; j++) {
          const w = rows[i].cells[j].childNodes[0].childNodes[0].offsetWidth
          arr[j] = this.columnWidth(w)
        }
      }
      // 截取数组
      arr.splice(0, 1)
      arr.splice(-1, 1)

      console.log('arr ---', arr)
      this.$props.tColumnData.forEach((item, key) => {
        item.width = arr[key] ? arr[key] : ''
      })
      this.tData.splice(0, 0)
    },
    clickMethods() {
      console.log('点击事件')
    },
    blurInputValue(filed, index, row, validateType, arr) {
      // 小数点取后两位
      if (validateType === 'int') {
        this.$props.tData[index][filed] = parseInt(this.$props.tData[index][filed], 10)
      } else if (validateType === 'float') {
        this.$props.tData[index][filed] = parseFloat(parseFloat(this.$props.tData[index][filed]).toFixed(2))
      }
      this.$props.tData.splice(0, 0)
      this.$emit('inputBlurCallBack', {
        filed: filed, index: index, value: row, arr: arr
      })
    },
    toggleRowSelectionMethods(rows, callback=() => {}) {
      if (rows) {
        // 未加载数据
        if(this.dataList.length === 0) {
          setTimeout(() => {
            this.toggleRowSelectionMethods(rows)
          }, 100)
        } else {
          this.clearSelectionMethods();
          this.$nextTick(() => {
            rows.forEach(row => {
              console.log('row ---', row)
              // 在数据源中查找
              const findIndex = this.dataList.findIndex((result) => {
                console.log('result ---', row, result)
                return row.id == result.id
              })
              if(findIndex !== -1) {
                console.log('find ---', findIndex, this.dataList[findIndex])
                this.$refs.commonTableRef.toggleRowSelection(this.dataList[findIndex], true);
              } else {
                this.$refs.commonTableRef.toggleRowSelection(row, true);
              }
            });
            // this.$refs.commonTableRef.toggleAllSelection()
            this.dataList.splice(0, 0)
          })
        }
      }
    },
    setOtherRowDisabled(row) {
      if(this.dataList.length === 0) {
        setTimeout(() => {
          this.setOtherRowDisabled(row)
        }, 100)
      } else {
        let tmpList = [...this.dataList]
        const findIndex = tmpList.findIndex((result) => {
          return result.id == row.id
        })
        if(findIndex !== -1) {
          this.$set(this.dataList[findIndex], 'isCanSelected', 1)
          tmpList.splice(findIndex, 1)
        }


        tmpList.forEach((item) => {
          const findChildIndex = this.dataList.findIndex((result) => {
            return result.id === item.id
          })
          if(findChildIndex !== -1) {
            this.$set(this.dataList[findChildIndex], 'isCanSelected', 0)
          }
        })
      }
    },
    refreshView() {
      this.dataList.splice(0, 0)
    },
    // 重置选中的航
    clearClickRow() {
      this.$refs.commonTableRef.setCurrentRow(null)
    },
    updateStatus(col, row, index, opt) {
      const currentData = row[col]
      let updateData = ''
      if (opt.indexOf(currentData) === 0) {
        [updateData] = [opt[1]]
      } else {
        [updateData] = [opt[0]]
      }
      this.$emit('switchUpdate', {
        col: col, data: row, index: index, updateValue: updateData
      })
    },
    handleSelectionChange(val) {
      this.selectedCache = val
      this.$emit(this.$props.emitSelectionName, val)
    },
    rowClickMethods(val) {
      this.$emit('tableRowClickEmit', val)
    },
    expandChangeMethods(val, expanded) {
      this.$emit('expandChangeEmit', {val: val, expanded: expanded})
    }
  }
}
</script>

<style scoped>
  .commonTable /deep/ .el-table__body .cell {
    padding: 0px 8px !important;
  }

  .page-nation{
    margin-top: 15px;
  }
</style>

<style>
// 全选隐藏
.DisableSelection .el-checkbox__input.is-disabled+span.el-checkbox__label{
  display: none!important;
}
</style>
